#include "term.h"

#include <assert.h>

#ifdef _WIN32
# include <windows.h>
#else
# include <unistd.h>
# include <sys/ioctl.h>
#endif

bool
sc_term_get_size(unsigned *rows, unsigned *cols) {
#ifdef _WIN32
    // windows平台
    CONSOLE_SCREEN_BUFFER_INFO csbi;

    /*
    GetStdHandle是一个Windows API函数。
    它用于从一个特定的标准设备（标准输入、标准输出或标准错误）中取得一个句柄（用来标识不同设备的数值）

    GetConsoleScreenBufferInfo，用于检索指定的控制台屏幕缓冲区的信息
    */
    bool ok =
        GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
    if (!ok) {
        return false;
    }

    if (rows) {
        assert(csbi.srWindow.Bottom >= csbi.srWindow.Top);
        *rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
    }

    if (cols) {
        assert(csbi.srWindow.Right >= csbi.srWindow.Left);
        *cols = csbi.srWindow.Right - csbi.srWindow.Left + 1;
    }

    return true;
#else
    struct winsize ws;

    /* 
    在计算机中，ioctl(input/output control)是一个专用于设备输入输出操作的系统调用,
    用于向设备发控制和配置命令.
    该调用传入一个跟设备有关的请求码，系统调用的功能完全取决于请求码。*/
    // 获取终端大小(以字符计，即每行都容纳多少个字符，一共多少行)    
    int r = ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
    if (r == -1) {
        return false;
    }

    if (rows) {
        *rows = ws.ws_row;
    }

    if (cols) {
        *cols = ws.ws_col;
    }

    return true;
#endif
}
